import { Component, Vue } from 'vue-property-decorator'

function broadcast (this: any, componentName: any, eventName: any, params: any) {
  this.$children.forEach((child: { $options: { componentName: any }; $emit: { apply: (arg0: any, arg1: any[]) => void } }) => {
    const name = child.$options.componentName

    if (name === componentName) {
      child.$emit.apply(child, [eventName].concat(params))
    } else {
      broadcast.apply(child, ([componentName, eventName].concat([params]) as any))
    }
  })
}
@Component({
  name: 'emitter'
})
export default class extends Vue {
  public dispatchEmitter (componentName?: any, eventName?: any, params?: any) {
    let parent = (this as any).$parent || (this as any).$root
    let name = parent.$options.componentName

    while (parent && (!name || name !== componentName)) {
      parent = parent.$parent

      if (parent) {
        name = parent.$options.componentName
      }
    }
    if (parent) {
      parent.$emit.apply(parent, [eventName].concat(params))
    }
  }

  private broadcast (componentName: any, eventName: any, params: any) {
    broadcast.call(this, componentName, eventName, params)
  }
}
